package ini

import (
	"bufio"
	"fmt"
	"io"
	"log"
	"os"
	"runtime"
	"strings"
	"time"
)

//注释行（程序要求）
var annotation string

//listener监听接口的设计
type Listener interface {
	listen(inifile string)
}
type ListenFunc func(string)

func (l ListenFunc) listen(inifile string) {
	l(inifile)
}

//初始化函数,使得 Unix 采用 # 作为注释行，Windows 采用 ; 作为注释行
func init() {
	if runtime.GOOS == "unix" {
		annotation = "#"
	} else {
		annotation = ";"
	}
}

//获得文件修改的时间
func GetModificationTime(inifile string) int64 {
	//打开ini配置文件
	file, err := os.Open(inifile)
	if err != nil {
		log.Println("Failed to open the inifile.")
		return time.Now().Unix()
	}

	//得到ini配置文件的信息（此处主要为了获得修改时间）
	fileinfo, err := file.Stat()
	if err != nil {
		log.Println("Failed to get the information of the inifile")
		return time.Now().Unix()
	}

	//关闭ini配置文件
	file.Close()

	//返回修改ini配置文件的时间
	return fileinfo.ModTime().Unix()
}

//核心函数Watch，通过文件和特殊的监听接口读取文件中的配置信息并返回
func Watch(filename string, listener Listener) (map[string]string, error) {
	//调用监听接口
	listener.listen(filename)

	config := make(map[string]string)

	f, err := os.Open(filename)
	if err != nil {
		panic(err)
	}

	//读取ini配置文件的信息
	r := bufio.NewReader(f)
	for {
		b, _, err := r.ReadLine()
		if err != io.EOF && err != nil {
			panic(err)
		}
		if err == io.EOF {
			break
		}

		//去处每行读取到的字符串两端的空格
		s := strings.TrimSpace(string(b))

		//index代表=的下标
		index := strings.Index(s, "=")
		if index < 0 {
			continue
		}

		//=前面的就是key值
		key := strings.TrimSpace(s[:index])
		if len(key) == 0 {
			continue
		}

		//=后面的是value值
		value := strings.TrimSpace(s[index+1:])
		if len(value) == 0 {
			continue
		}

		// 将key和value相对应
		config[key] = value

		// 按行打印去处空格后的字符串s，以便查看配置信息及其变化
		fmt.Println(s)
	}

	f.Close()

	return config, nil
}

//按key值输出其对应的value值
func PrintValue(config map[string]string, key string) {
	fmt.Println(key, "=", config[key])
}
